package kr.ac.kaist.pointdaproject;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class CardRegistration extends Activity {
	private static final String TAG = "CardRegistration";
	
    private static final String[] PROJECTION =
            new String[] {
                PointCard.Cards._ID,
                PointCard.Cards.COLUMN_POINTCARDS_IMAGE,
                PointCard.Cards.COLUMN_POINTCARDS_NAME,
                PointCard.Cards.COLUMN_POINTCARDS_NUMBER
        };

	public static final int REQUEST_PREDEFINED_CARD = 1;

	private static final int STATE_INSERT = 1;
	private static final int STATE_EDIT = 2;
	private static final int BARCODE_TIMER_OUT = 1;

	private int mState;
    private Uri mUri;
    private Cursor mCursor;
	private CardItem mCards;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.card_registration);
        
        Intent intent = getIntent();
        if (intent.getData() == null) {
            intent.setData(PointCard.Cards.CONTENT_URI);
        }

        View view = findViewById(R.id.card); 
        view.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
            	Intent intent = new Intent(CardRegistration.this, CardPredefinedListActivity.class);
    			startActivityForResult(intent, REQUEST_PREDEFINED_CARD);
            }
        });

        EditText editText = (EditText) findViewById(R.id.card_number);
        editText.setOnKeyListener(new OnKeyListener() {
			@Override
			public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
				mHandler.removeMessages(BARCODE_TIMER_OUT);
				mHandler.sendEmptyMessageDelayed(BARCODE_TIMER_OUT, 1000);
				return false;
			}
        });
        
        mCards = new CardItem();
        
        final String action = intent.getAction();
        mUri = intent.getData();
        mCursor = managedQuery(
                mUri,         // The URI that gets multiple notes from the provider.
                PROJECTION,   // A projection that returns the note ID and note content for each note.
                null,         // No "where" clause selection criteria.
                null,         // No "where" clause selection values.
                null          // Use the default sort order (modification date, descending)
            );
        mCursor.moveToFirst();
        
        if (Intent.ACTION_EDIT.equals(action)) {
            mState = STATE_EDIT;
            int colImageIndex = mCursor.getColumnIndex(PointCard.Cards.COLUMN_POINTCARDS_IMAGE);
            int colNameIndex = mCursor.getColumnIndex(PointCard.Cards.COLUMN_POINTCARDS_NAME);
            int colNumberIndex = mCursor.getColumnIndex(PointCard.Cards.COLUMN_POINTCARDS_NUMBER);
            
            String image = mCursor.getString(colImageIndex);
            String name = mCursor.getString(colNameIndex);
            String number = mCursor.getString(colNumberIndex);
            
            setView(image, name, number);
            
            createBarcode();
        } else {
        	mState = STATE_INSERT;
        	
            if (mUri == null) {

                // Writes the log identifier, a message, and the URI that failed.
                Log.e(TAG, "Failed to insert new card into " + getIntent().getData());

                // Closes the activity.
                finish();
                return;
            }        	
        	setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        
        if(mCursor != null) {
            // Requery in case something changed while paused (such as the title)
            mCursor.requery();

            /* Moves to the first record. Always call moveToFirst() before accessing data in
             * a Cursor for the first time. The semantics of using a Cursor are that when it is
             * created, its internal index is pointing to a "place" immediately before the first
             * record.
             */
            mCursor.moveToFirst();
        }
    }

    private void setView(String icon, String name) {
    	mCards.getCardName().set(name);
    	mCards.getCardIcon().set(icon);

    	TextView cardname = (TextView) findViewById(R.id.name);
    	cardname.setText(name);
    	
    	ImageView cardIcon = (ImageView) findViewById(R.id.icon);
    	if(icon == null) {
    		icon = "card1";
    	}
    	cardIcon.setImageResource(getResources().getIdentifier(icon, "drawable", "kr.ac.kaist.pointdaproject")); 
    }

    private void setView(String icon, String name, String number) {
    	setView(icon, name);

        mCards.getCardNumber().set(number);

        EditText editText = (EditText) findViewById(R.id.card_number);
        editText.setText(number);   
        if(number != null) {
            editText.setSelection(number.length());        	
        }
    }

    Handler mHandler = new Handler(new HandlerCallback());
	class HandlerCallback implements Handler.Callback {
    	@Override
    	public boolean handleMessage(Message msg){
    		if(msg.what == BARCODE_TIMER_OUT) {
    			createBarcode();
    		}
    		return true;
    	}
	};

	
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // The preferences returned if the request code is what we had given
        // earlier in startSubActivity
        if (requestCode == REQUEST_PREDEFINED_CARD) {
            // Read a sample value they have set
            if(data != null) {
            	String icon = data.getStringExtra("icon");
            	String name = data.getStringExtra("name");
            	
            	setView(icon, name);
            }
        }
    }

	private void createBarcode() {
		EditText cardNumber = (EditText) findViewById(R.id.card_number);
		
		CardBarcodeView barcode = (CardBarcodeView) findViewById(R.id.barcode);
		barcode.setCardBarcodeFormat(com.google.zxing.BarcodeFormat.CODE_128);
		barcode.setCardNumber(cardNumber.getText().toString());
		barcode.create();
	}
	

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        
        // Inflate the menu; this adds items to the action bar if it is present.
        //getMenuInflater().inflate(R.menu.main, menu);
        //return true;
    	getMenuInflater().inflate(R.menu.pointcard_menu, menu);
    	return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.menu_save) {
        	if(saveCard())
        		finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private final boolean saveCard() {
    	boolean ret = false;
    	
    	EditText cardNumber = (EditText) findViewById(R.id.card_number);
    	if(cardNumber != null) {
    		mCards.getCardNumber().set(cardNumber.getText().toString());
    	}        	

    	String number = mCards.getCardNumber().get();
    	String name = mCards.getCardName().get();
    	String icon = mCards.getCardIcon().get();
    	
    	if(number.length() > 0 && name.length() > 0 && icon.length() > 0) {
            // Sets up a map to contain values to be updated in the provider.
            ContentValues values = new ContentValues();
            values.put(PointCard.Cards.COLUMN_NAME_MODIFICATION_DATE, System.currentTimeMillis());

            // If the action is to insert a new note, this creates an initial title for it.
            if (mState == STATE_INSERT) {

                // If no title was provided as an argument, create one from the note text.
                if (name == null) {
      
                    // Get the note's length
                    int length = number.length();

                    // Sets the title by getting a substring of the text that is 31 characters long
                    // or the number of characters in the note plus one, whichever is smaller.
                    name = number.substring(0, Math.min(30, length));
      
                    // If the resulting length is more than 30 characters, chops off any
                    // trailing spaces
                    if (length > 30) {
                        int lastSpace = name.lastIndexOf(' ');
                        if (lastSpace > 0) {
                        	name = name.substring(0, lastSpace);
                        }
                    }
                }
                // In the values map, sets the value of the title
                values.put(PointCard.Cards.COLUMN_POINTCARDS_NAME, name);
            } else if (name != null) {
                // In the values map, sets the value of the title
                values.put(PointCard.Cards.COLUMN_POINTCARDS_NAME, name);
            }

            // This puts the desired notes text into the map.
            values.put(PointCard.Cards.COLUMN_POINTCARDS_NUMBER, number);

            values.put(PointCard.Cards.COLUMN_POINTCARDS_IMAGE, icon);
    	
            /*
             * Updates the provider with the new values in the map. The ListView is updated
             * automatically. The provider sets this up by setting the notification URI for
             * query Cursor objects to the incoming URI. The content resolver is thus
             * automatically notified when the Cursor for the URI changes, and the UI is
             * updated.
             * Note: This is being done on the UI thread. It will block the thread until the
             * update completes. In a sample app, going against a simple provider based on a
             * local database, the block will be momentary, but in a real app you should use
             * android.content.AsyncQueryHandler or android.os.AsyncTask.
             */
            if(mState == STATE_INSERT) {
                getContentResolver().insert(
                        mUri,    // The URI for the record to update.
                        values   // The map of column names and new values to apply to them.
                    );    		
            } else {
                getContentResolver().update(
                        mUri,    // The URI for the record to update.
                        values,  // The map of column names and new values to apply to them.
                        null,    // No selection criteria are used, so no where columns are necessary.
                        null     // No where columns are used, so no where arguments are necessary.
                    );    		
            }
        	Toast.makeText(CardRegistration.this, R.string.card_create_success, Toast.LENGTH_LONG).show();
        	ret = true;
    	} else {
        	Toast.makeText(CardRegistration.this, R.string.card_create_fail, Toast.LENGTH_LONG).show();
    	}
    	return ret;
    }
    
    /**
     * A placeholder fragment containing a simple view.
     */
    /*
    public static class PlaceholderFragment extends Fragment {

		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);
			return rootView;
		}
	}
	*/

}
